<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>批量合成音频/识别字幕</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
      }

      body {
        padding: 20px;
        color: #333;
        font-size: 14px;
      }

      /* 遮罩层 */
      .overlay {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        z-index: 1;
      }

      /* 弹窗样式 */
      .modal {
        display: none;
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background: #fff;
        padding: 20px;
        box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
        z-index: 2;
        width: 300px;
        text-align: center;
        border-radius: 10px;
      }

      /* 关闭按钮 */
      .close-btn {
        background-color: #f44336;
        color: white;
        border: none;
        padding: 5px 10px;
        cursor: pointer;
        border-radius: 5px;
        margin-top: 10px;
      }

      .close-btn:hover {
        background-color: #d32f2f;
      }

      .container {
        font-size: 20px;
      }

      .description {
        line-height: 1.6;
        margin-bottom: 20px;
      }

      .actions {
        margin-bottom: 20px;
        display: flex;
        align-items: center;
        gap: 10px;
      }

      .btn {
        padding: 6px 12px;
        border-radius: 4px;
        border: none;
        cursor: pointer;
      }

      .btn-primary {
        background: #5048e5;
        color: white;
        margin-right: 10px;
      }

      .btn-default {
        background: #fff;
        border: 1px solid #d9d9d9;
      }

      .input-group {
        display: flex;
        align-items: center;
        margin-left: 10px;
      }

      .input-group input {
        width: 300px;
        padding: 4px 11px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        margin-right: 10px;
      }

      .settings {
        margin: 20px 0;
        display: flex;
        align-items: center;
        gap: 20px;
      }

      .color-picker {
        background: #f0f0f0;
        padding: 2px 8px;
        border-radius: 2px;
        margin-left: 5px;
      }

      .speed-input {
        width: 60px;
        padding: 2px 6px;
        border: 1px solid #d9d9d9;
        border-radius: 2px;
      }

      .status {
        display: flex;
        align-items: center;
        gap: 10px;
        margin: 20px 0;
      }

      .status-btn {
        padding: 4px 15px;
        border-radius: 2px;
        border: 1px solid #d9d9d9;
        background: #fff;
        cursor: pointer;
        margin-right: 10px;
      }

      .status-text {
        color: #ff4d4f;
      }

      table {
        width: 100%;
        border-collapse: collapse;
      }

      th,
      td {
        padding: 12px 8px;
        text-align: left;
        border-bottom: 1px solid #f0f0f0;
      }

      th {
        background: #fafafa;
        font-weight: 500;
      }

      .empty-state {
        text-align: center;
        padding: 40px 0;
        color: #999;
      }

      .empty-state img {
        width: 60px;
        height: 60px;
        margin-bottom: 10px;
        opacity: 0.3;
      }

      /* 隐藏原生单选框 */
      .custom-radio input {
        position: absolute;
        opacity: 0;
        cursor: pointer;
      }

      /* 自定义单选框外观 */
      .custom-radio .radio-icon {
        position: relative;
        display: inline-block;
        width: 18px;
        height: 18px;
        border: 2px solid #999;
        border-radius: 50%;
        margin-right: 10px;
        vertical-align: middle;
        transition: all 0.3s ease;
        top: -3px;
      }

      /* 选中状态样式 */
      .custom-radio input:checked ~ .radio-icon {
        border-color: #5048e5;
        background-color: #5048e5;
        box-shadow: inset 0 0 0 3px white; /* 内圆效果 */
      }

      /* 悬浮交互效果 */
      .custom-radio:hover .radio-icon {
        border-color: #555;
      }

      /* 禁用状态 */
      .custom-radio input:disabled ~ .radio-icon {
        background-color: #eee;
        border-color: #ccc;
      }

            /* 隐藏原生复选框 */
      .custom-checkbox input {
        position: absolute;
        opacity: 0;
        cursor: pointer;
        height: 0;
        width: 0;
      }

      /* 自定义复选框外观 */
      .custom-checkbox .checkmark {
        position: relative;
        display: inline-block;
        width: 18px;
        height: 18px;
        background-color: #fff;
        border: 2px solid #ccc;
        border-radius: 3px;
        margin-right: 8px;
        vertical-align: middle;
        top: -3px;
      }

      /* 选中状态样式 */
      .custom-checkbox input:checked ~ .checkmark {
        background-color: #5048e5;
        border-color: #5048e5;
      }

      /* 勾选图标（使用伪元素） */
      .custom-checkbox .checkmark:after {
        content: "";
        position: absolute;
        display: none;
        left: 3px;
        top: -1px;
        width: 5px;
        height: 10px;
        border: solid white;
        border-width: 0 2px 2px 0;
        transform: rotate(45deg);
      }

      .custom-checkbox input:checked ~ .checkmark:after {
        display: block;
      }
    </style>
    <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
  </head>

  <body>
    <div class="container">
      <div id="overlay" class="overlay" onclick="closeModal()"></div>

      <div id="modal" class="modal">
        <p id="message">消息弹窗</p>
        <!-- TODO: 调整消息弹窗样式 -->
        <button class="close-btn" onclick="closeModal()">关闭</button>
      </div>

      <div class="description">
        任务类型：<br />1. 文案-配音 2. 音视频 -> 字幕
        <br />
        <br />
        功能说明：
        <br />1. 导入文案：将文案文件导入到任务列表中，并自动生成配音文件。
        <br />2.
        导入音/视频：将音/视频文件导入到任务列表中，并自动生成字幕文件。
        <br />3. 导出目录：选择导出目录，将任务列表中的文件导出到指定目录。
        <br />注意: 每次只能选择单一任务类型
      </div>

      <div class="actions">
        <button class="btn btn-primary" onclick="export_files('text')">
          导入文案
        </button>
        <button class="btn btn-primary" onclick="export_files('audio/video')">
          导入音/视频
        </button>
        <div class="input-group">
          <span>导出目录：</span>
          <input
            type="text"
            placeholder="请输入"
            id="export-dir"
            readonly
            onclick="chooseFolder('export-dir')"
            value=""
          />
        </div>
      </div>

      <div class="settings">
        <h3>选择任务类型：</h3>
        <form id="radioForm">
          <div>
            <label class="custom-radio">
              <input type="radio" id="audio" name="radioGroup" value="audio" />
              <span class="radio-icon"></span>
              <label for="audio">配音</label>
            </label>
          </div>
          <div>
            <label class="custom-radio">
              <input
                type="radio"
                id="subtitle"
                name="radioGroup"
                value="subtitle"
              />
              <span class="radio-icon"></span>
              <label for="subtitle">字幕</label>
            </label>
          </div>
        </form>
        <div class="voice-color-select" style="display: none">
          <label for="voiceColor">选择声音:</label>
          <select id="voiceColor"></select>
        </div>
      </div>
      <div class="status">
        <button class="status-btn" onclick="start_work()">开始任务</button>
        <button class="status-btn" onclick="stop_work()">终止任务</button>
      </div>

      <div>
        已选择<span id="checked-count">0</span>个文件(共<span id="upload-count"
          >0</span
        >个文件)
      </div>

      <table>
        <thead>
          <tr>
            <th style="width: 40px">
              <label class="custom-checkbox">
                <input type="checkbox" id="selectAll" />
                <span class="checkmark"></span>
              </label>
            </th>
            <th>序号</th>
            <th>文件名</th>
            <th>时长/秒</th>
            <th>大小</th>
            <th>状态</th>
          </tr>
        </thead>
        <tbody id="file-list"></tbody>
      </table>
    </div>
    <script type="text/javascript">
      document.addEventListener("DOMContentLoaded", function () {
        let file_items = [];

        new QWebChannel(parent.qt.webChannelTransport, function (channel) {
          Bridge = channel.objects.Bridge;

          Bridge.result.connect(function (result) {
            document.querySelector(
              "tr[data-id='" + result + "']td[6]"
            ).textContent = "已完成";
          });

          Bridge.batch_ident_and_synthesis_result.connect(function (result) {
            const tbody = document.getElementById("file-list");
            if (!tbody) {
              return;
            }
            let context_item = [];
            for (let file_item of JSON.parse(result)) {
              // 通过file_item的file来去重
              let status = file_items.filter(
                (item) => item.file === file_item.file
              );
              if (status.length === 0) {
                let current_id = file_items.length + 1;

                context_item.push(`
                                        <tr data-id="${current_id}">
                                            <td>
                                              <label class="custom-checkbox">
                                                <input type="checkbox" class='row-check' value="${file_item.file}" />
                                                <span class="checkmark"></span>
                                              </label>
                                            </td>
                                            <td>${current_id}</td>
                                            <td>${file_item.file}</td>
                                            <td>${file_item.duration}</td>
                                            <td>${file_item.size}</td>
                                            <td>${
                                              file_item.status || "未开始"
                                            }</td>
                                        </tr>
                                    `);
                file_item["id"] = current_id;
                file_item["status"] = "未开始";
                file_item["selected"] = false;
                file_items.push(file_item);
              }
            }
            if (context_item.length > 0) {
              tbody.innerHTML += context_item.join("");
              document.getElementById("upload-count").innerText =
                file_items.length;
              // 绑定每个行复选框：当所有被选中时自动勾选表头全选
              document.querySelectorAll(".row-check").forEach((cb) => {
                cb.addEventListener("change", function (event) {
                  const all = document.querySelectorAll(".row-check");
                  const checked =
                    document.querySelectorAll(".row-check:checked");
                  document.getElementById("checked-count").checked =
                    all.length === checked.length;
                  document.getElementById("checked-count").innerText =
                    checked.length;
                  if (cb.checked) {
                    for (let item of file_items) {
                      if (item.file === event.target.value) {
                        item.selected = true;
                      }
                    }
                  } else {
                    for (let item of file_items) {
                      if (item.file === event.target.value) {
                        item.selected = false;
                      }
                    }
                  }
                });
              });
            }
          });

          window.export_files = function (suffix) {
            Bridge.batch_ident_and_synthesis(suffix);
          };
          // 选择的文件夹信号槽
          Bridge.select_folder_result.connect(function (eid, path) {
            document.getElementById(eid).value = path;
          });

          window.chooseFolder = function (eid) {
            Bridge.choose_folder(eid);
          };

          window.load_audio_metrail = function () {
            Bridge.load_audio_model();
          };

          Bridge.load_audio_model_result.connect(function (content) {
            let audio_models = JSON.parse(content);
            let voiceColorSelect = document.getElementById("voiceColor");
            if (!voiceColorSelect) {
              return;
            }
            voiceColorSelect.innerHTML = audio_models
              .map(
                (model) => `
                                        <option value="${model.model};${model.voice}">${model.tone_name}</option>
                                    `
              )
              .join("");
          });

          window.start_work = function () {
            let work_channel =
              document.getElementById("radioForm").elements["radioGroup"].value;
            let voice_color = document.getElementById("voiceColor").value;
            let file_list = file_items.filter((item) => item.selected);
            let output_dir = document.getElementById("export-dir").value;
            if (output_dir === "") {
              showModal("请选择导出目录");
              return;
            }
            if (file_list.length === 0) {
              showModal("请先选择文件");
              return;
            }
            Bridge.batch_synthesis_or_ident(
              JSON.stringify({
                files: file_list,
                channel: work_channel,
                voice: voice_color,
                output_dir: output_dir,
              })
            );
          };
          window.stop_work = function () {
            Bridge.stop();
          };

          load_audio_metrail();
        });

        window.showModal = function (message) {
          document.getElementById("message").innerText = message;
          document.getElementById("overlay").style.display = "block";
          document.getElementById("modal").style.display = "block";
        };

        window.closeModal = function () {
          document.getElementById("overlay").style.display = "none";
          document.getElementById("modal").style.display = "none";
        };

        // 绑定全选框
        document
          .getElementById("selectAll")
          .addEventListener("change", function () {
            const isChecked = this.checked;
            document
              .querySelectorAll(".row-check")
              .forEach((cb) => (cb.checked = isChecked));
            document.getElementById("checked-count").innerText = isChecked
              ? file_items.length
              : 0;
            for (let item of file_items) {
              item.selected = isChecked;
            }
          });
        // 监听单选框的变化
        document.getElementById("option1").addEventListener("change", () => {
          let voiceColorSelect = document.querySelector(".voice-color-select");
          if (option1.checked) {
            voiceColorSelect.style.display = "block"; // 显示下拉框
          } else {
            voiceColorSelect.style.display = "none"; // 隐藏下拉框
          }
        });
      });
    </script>
  </body>
</html>
